package com.csjbot.snowbot_rogue.utils;


import com.csjbot.csjbase.log.Csjlogger;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Random;

/**
 * Json结果解析类
 */
public class JsonParser {

    public static String parseIatResult(String json) {
        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                // 转写结果词，默认使用第一个结果
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                JSONObject obj = items.getJSONObject(0);
                ret.append(obj.getString("w"));
//				如果需要多候选结果，解析数组其他字段
//				for(int j = 0; j < items.length(); j++)
//				{
//					JSONObject obj = items.getJSONObject(j);
//					ret.append(obj.getString("w"));
//				}
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret.toString();
    }

    public static String parseGrammarResult(String json, String engType) {
        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            JSONArray words = joResult.getJSONArray("ws");
            // 云端和本地结果分情况解析
            if ("cloud".equals(engType)) {
                for (int i = 0; i < words.length(); i++) {
                    JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                    for (int j = 0; j < items.length(); j++) {
                        JSONObject obj = items.getJSONObject(j);
                        if (obj.getString("w").contains("nomatch")) {
                            ret.append("没有匹配结果.");
                            return ret.toString();
                        }
                        ret.append("【结果】" + obj.getString("w"));
                        ret.append("【置信度】" + obj.getInt("sc"));
                        ret.append("\n");
                    }
                }
            } else if ("local".equals(engType)) {
                ret.append("【结果】");
                for (int i = 0; i < words.length(); i++) {
                    JSONObject wsItem = words.getJSONObject(i);
                    JSONArray items = wsItem.getJSONArray("cw");
                    if ("<contact>".equals(wsItem.getString("slot"))) {
                        // 可能会有多个联系人供选择，用中括号括起来，这些候选项具有相同的置信度
                        ret.append("【");
                        for (int j = 0; j < items.length(); j++) {
                            JSONObject obj = items.getJSONObject(j);
                            if (obj.getString("w").contains("nomatch")) {
                                ret.append("没有匹配结果.");
                                return ret.toString();
                            }
                            ret.append(obj.getString("w")).append("|");
                        }
                        ret.setCharAt(ret.length() - 1, '】');
                    } else {
                        //本地多候选按照置信度高低排序，一般选取第一个结果即可
                        JSONObject obj = items.getJSONObject(0);
                        if (obj.getString("w").contains("nomatch")) {
                            ret.append("没有匹配结果.");
                            return ret.toString();
                        }
                        ret.append(obj.getString("w"));
                    }
                }
                ret.append("【置信度】" + joResult.getInt("sc"));
                ret.append("\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
            ret.append("没有匹配结果.");
        }
        return ret.toString();
    }

    public static String parseGrammarResult(String json) {
        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                for (int j = 0; j < items.length(); j++) {
                    JSONObject obj = items.getJSONObject(j);
                    if (obj.getString("w").contains("nomatch")) {
                        ret.append("没有匹配结果.");
                        return ret.toString();
                    }
                    ret.append("【结果】" + obj.getString("w"));
                    ret.append("【置信度】" + obj.getInt("sc"));
                    ret.append("\n");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            ret.append("没有匹配结果.");
        }
        return ret.toString();
    }

    public static String parseUnderstandResult(String json) {
        return parseUnderstandResult(json, null);
    }

    public static String parseUnderstandResult(String json, SpeechParserCallBack callBack) {
        StringBuffer ret = new StringBuffer();

        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            if (joResult.getString("rc").endsWith("0")) {
                switch (joResult.getString("service")) {
                    case "music":
                        return parseMusic(joResult, callBack);
                    case "weather":
                        return parseWeather(joResult, callBack);
                    case "map":
                        return parseMap(joResult, callBack);
                    case "schedule":
                        return parseSchedule(joResult, callBack);
                    case "flower":
                        return parseFlower(joResult, callBack);
                    case "gift":
                        return parseGift(joResult, callBack);
                    case "cookbook":
                        return parseCookbook(joResult, callBack);
                    case "websearch":
                        return parseWebSearch(joResult, callBack);
                    case "translation":
                        return parserTranslation(joResult, callBack);
                    case "flight":
                        return parserFlight(joResult, callBack);
                    case "pm25":
                        return parserPM25(joResult, callBack);
                    case "train":
                        return parseTrain(joResult, callBack);
                    case "tv":
                        return parseTV(joResult, callBack);
                    case "telephone":
                        return parseTelephone(joResult, callBack);
                    case "app":
                        return parseApp(joResult, callBack);
                    case "restaurant":
                        return parseRestaurant(joResult, callBack);
                    case "hotel":
                        return parseHotel(joResult, callBack);
                    default:
                        return joResult.getJSONObject("answer").getString("text");
                }
            } else {
                if (callBack != null) {
                    int errorCode = Integer.parseInt(joResult.getString("rc"));
                    callBack.parserError(errorCode);
                }
                return "";
            }
        } catch (JSONException e) {
            Csjlogger.error(e.getMessage());
            ret.append("好像出错了，我不知道答案");
        }
        return ret.toString();
    }


    private static String parseHotel(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String date = slot.getJSONObject("checkinDate").getString("date");
        String city = slot.getJSONObject("location").getString("city");
        String name = slot.isNull("name") ? "酒店" : slot.getString("name");
        String str = "";
        if (city.equals("CURRENT_CITY") && slot.isNull("area")) {
            str = "小雪这就为您搜索" + name;
        } else if (slot.isNull("area")) {
            str = "小雪这就为您搜索" + city + "的" + name;
        } else {
            str = "小雪这就为您搜索" + city + slot.getString("area") + "的" + name;
        }
        return str;
    }

    private static String parseRestaurant(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String kind = !slot.isNull("name") ? slot.getString("name") : slot.getString("category");
        String city = slot.getString("city");
        String str = "";
        if (city.equals("CURRENT_CITY") && slot.isNull("area")) {
            str = "小雪这就为您搜索" + kind;
        } else if (slot.isNull("area")) {
            str = "小雪这就为您搜索" + city + "的" + kind;
        } else {
            str = "小雪这就为您搜索" + city + slot.getString("area") + "的" + kind;
        }
        return str;
    }

    private static String parseApp(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        String name = joResult.getJSONObject("semantic").getJSONObject("slots").getString("name");
        String operation = "";
        switch (joResult.getString("operation")) {
            case "LAUNCH":
                operation = "打开";
                break;
            case "QUERY":
                operation = "搜索";
                break;
            case "DOWNLOAD":
                operation = "下载";
                break;
            default:
                break;
        }
        return "小雪这就为您" + operation + name;
    }

    private static String parseTelephone(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject semantic = joResult.getJSONObject("semantic");
        String str = "";
        if (semantic.isNull("name") && semantic.isNull("code")) {
            str = "请问您想打给谁";
        } else if (!semantic.isNull("name") || !semantic.isNull("code")) {
            String name = !semantic.isNull("name") ? semantic.getString("name") : semantic.getString("code");
            str = "小雪这就为您拨打" + name + "的电话";
        }
        return str;
    }

    private static String parseTV(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        String str = "";
        if (joResult.getJSONObject("data").isNull("result")) {
            str = "小雪这就为您呈现搜索结果";
        } else {
            JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
            int len = array.length();
            str = "小雪已搜索到" + len + "个结果，这就为您呈现";
        }
        if (callBack != null) {
            callBack.parserWebService(joResult.getJSONObject("webPage").getString("url"));
        }
        return str;
    }

    private static String parseGift(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String name = !slot.isNull("name") ? slot.getString("name") : slot.getString("category");
        JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
        int len = array.length();

        if (callBack != null) {
            callBack.parserWebService(joResult.getJSONObject("webPage").getString("url"));
        }

        return "小雪这就为您搜索" + name + " ,共搜到" + len + "个结果，这就为您呈现";
    }

    private static String parseCookbook(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String name = !slot.isNull("dishName") ? slot.getString("dishName") : slot.getString("ingredient");
        JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
        int len = array.length();

        if (callBack != null) {
            callBack.parserWebService(joResult.getJSONObject("webPage").getString("url"));
        }

        return "小雪这就为您搜索" + name + " ,共搜到" + len + "个结果，这就为您呈现";
    }

    private static String parseFlower(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        String name = joResult.getJSONObject("semantic").getJSONObject("slots").getString("category");
        JSONArray array = joResult.getJSONObject("data").getJSONArray("result");
        int len = array.length();

        if (callBack != null) {
            callBack.parserWebService(joResult.getJSONObject("webPage").getString("url"));
        }

        return "小雪这就为您搜索" + name + " ,共搜到" + len + "个结果，这就为您呈现";
    }

    private static String parserPM25(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        JSONArray results = joResult.getJSONObject("data").getJSONArray("result");
        String str = null;
        if (slot.isNull("city")) {
            str = "请问您询问的是" + slot.getString("province") + "哪里的空气质量";
        } else {
            String area = slot.isNull("area") ? slot.getString("city") : slot.getString("area");
            for (int i = 0; i < results.length(); i++) {
                JSONObject resault = (JSONObject) results.get(i);
                Csjlogger.debug(resault.getString("date"));

                if (resault.getString("subArea").equals(area)) {
                    str = resault.getString("province") + area + "的pm25为，" +
                            resault.getString("pm25") + "，空气质量 " +
                            resault.getString("quality");
                }
            }
        }
        if (callBack != null) {
            callBack.parserWeather(joResult.getJSONObject("webPage").getString("url"));
        }
        return str;
    }

    private static String parserFlight(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
//        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
//
//        String date = !slot.isNull("startDate") ? slot.getJSONObject("startDate").getString("dateOrig") : "今天";
//        String type = !slot.isNull("type") ? slot.getString("type") : "单程";
//        String startLoc = !slot.getJSONObject("startLoc").isNull("city") ? slot.getJSONObject("startLoc").getString("city") : slot.getJSONObject("startLoc").getString("area");
//        String endLoc = !slot.getJSONObject("endLoc").isNull("city") ? slot.getJSONObject("endLoc").getString("city") : slot.getJSONObject("endLoc").getString("area");
//        String url = "";
//        String str = "小雪这就为您搜索" + date + "从" + startLoc + "到" + endLoc + "的" + type + "机票";

        return "机票查询功能暂时未开放，小雪接下来会为您开放的";
    }

    private static String parseTrain(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");

        String Url = " ";
        String date = !slot.isNull("startDate") ? slot.getJSONObject("startDate").getString("dateOrig") : "今天";
        String startLoc = slot.getJSONObject("startLoc").getString("city");
        String endLoc = slot.getJSONObject("endLoc").getString("city");
        String category = !slot.isNull("category") ? slot.getString("category") : "火车";

        if (callBack != null) {
            callBack.parserWebService(String.format(Url, date, startLoc, endLoc, category));
        }

        return "小雪这就为您搜索" + date + startLoc + "到" + endLoc + "的" + category;
    }

    private static String parserTranslation(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");

        String target = slot.getString("target");
        String source = "zh";
        String content = slot.getString("content");
        String targetSay = "英语";
        String url = "http://fanyi.baidu.com/?aldtype=16047#%s/%s/%s";

        switch (target) {
            case "ja":
                target = "jp";
                targetSay = "日语";
                break;
            case "ko":
                target = "kor";
                targetSay = "韩语";
                break;
            default:
                break;
        }

        StringBuilder sb = new StringBuilder();
        sb.append("小雪这就为您把").append(content).append("翻译成").append(targetSay);

        try {
            if (callBack != null) {
                callBack.parserWebService(String.format(url, source, target, URLDecoder.decode(content, "utf-8")));
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return sb.toString();
    }

    /**
     * @param
     * @Description: 网络查询
     * @author Administrator
     * @time 2016/8/11 0011
     */
    private static String parseWebSearch(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        // TODO 有BUG {"semantic":{"slots":{"keywords":"乔布斯"}},"rc":0,"operation":"QUERY","service":"video","text":"百度乔布斯"}
        JSONObject slot = joResult.getJSONObject("semantic").getJSONObject("slots");
        String channel = !slot.isNull("channel") ? slot.getString("channel") : "baidu";
        String sayChannel = "百度";
        String channelUrl = "https://www.baidu.com.cn/s?wd=%s&cl=3";
        switch (channel) {
            case "google":
//                channelUrl = "www.google.com";
//                sayChannel = "谷歌";
                return "小雪提醒您，国内可上不了谷歌哦";
            case "taobao":
                channelUrl = "https://s.taobao.com/search?q=%s";
                sayChannel = "淘宝";
                break;
        }
        String keywords = slot.getString("keywords");

        if (callBack != null) {
            callBack.parserWebService(String.format(channelUrl, keywords));
        }
        return "小雪这就为您用" + sayChannel + " ,搜索" + keywords;
    }

    /**
     * @param
     * @Description:
     * @author Administrator
     * @time 2016/8/11 0011
     */
    private static String parseSchedule(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject slots = joResult.getJSONObject("semantic").getJSONObject("slots");
        String timeOrig = slots.getString("timeOrig");
        String dateOrig = slots.isNull("dateOrig") ? "今天" : slots.getString("dateOrig");

        return "小雪这就为您设置" + dateOrig + timeOrig + "的闹钟";
    }

    /**
     * @param
     * @Description: 解析地图场景
     * @author Administrator
     * @time 2016/8/11 0011
     * TODO 需要做的更加好
     */
    private static String parseMap(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        StringBuilder sb = new StringBuilder();

        switch (joResult.getString("operation")) {
            case "ROUTE":
                JSONObject endLocObj = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("endLoc");
                String end = endLocObj.isNull("city") ? endLocObj.getString("area") : endLocObj.getString("city");
                JSONObject startLocObj = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("startLoc");
                String start = startLocObj.isNull("city") ? startLocObj.getString("area") : startLocObj.getString("city");

                if (start.equalsIgnoreCase("CURRENT_CITY")) {
                    start = "昆山";
                }

                sb.append("小雪是路盲，不知道从").append(start).append("到").append(end).append("怎么去").toString();
                break;
            case "POSITION":
                JSONObject location = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("location");
                String area = location.isNull("area") ? location.getString("city") : location.getString("area");
                sb.append("小雪这就为您定位").append(area);
                break;
            default:
                break;
        }

        return sb.toString();
    }

    private static String parseWeather(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONObject dataTimeObj = joResult.getJSONObject("semantic").getJSONObject("slots").getJSONObject("datetime");
        JSONArray results = joResult.getJSONObject("data").getJSONArray("result");
        boolean checkDateOut = false;

        // 小雪要说出的天气
        String dateString = "今天";

        // 确实获取的准确日子
        String date = dataTimeObj.getString("date");
        String str = "";

        if (!date.equals("CURRENT_DAY")) {
            dateString = dataTimeObj.getString("dateOrig");
        } else {
            JSONObject resault = (JSONObject) results.get(0);

            str = resault.getString("city") + dateString + "天气，" +
                    resault.getString("wind") + "，" +
                    resault.getString("weather") + "，" +
                    resault.getString("tempRange");

            if (!resault.isNull("airQuality") && !resault.getString("airQuality").isEmpty()) {
                str += ",  空气质量" + resault.getString("airQuality");
            }
        }

        for (int i = 0; i < results.length(); i++) {
            JSONObject resault = (JSONObject) results.get(i);
            Csjlogger.debug(resault.getString("date"));

            if (resault.getString("date").equals(date)) {
                str = resault.getString("city") + dateString + "天气，" +
                        resault.getString("wind") + "，" +
                        resault.getString("weather") + "，" +
                        resault.getString("tempRange");

                if (!resault.isNull("airQuality") && !resault.getString("airQuality").isEmpty()) {
                    str += ",  空气质量" + resault.getString("airQuality");
                }

                checkDateOut = false;
                break;
            }
            checkDateOut = true;
        }

        if (checkDateOut) {
            return "您说的日子离今天太远啦，小雪没有办法为您查到。";
        }

        if (callBack != null) {
            JSONObject objURL = joResult.getJSONObject("webPage");
            callBack.parserWeather(objURL.getString("url"));
        }

        return str;
    }

    private static String parseMusic(JSONObject joResult, SpeechParserCallBack callBack) throws JSONException {
        JSONArray ja = joResult.getJSONObject("data").getJSONArray("result");

        if (callBack != null) {
            JSONObject selectSong = ja.getJSONObject(new Random().nextInt(ja.length()));
            callBack.parserMusic(selectSong.getString("downloadUrl"), selectSong.getString("singer"), selectSong.getString("name"));
        }

        return ja.getJSONObject(0).getString("downloadUrl");
    }

    public static String parseWebPageResult(String json) {
        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            if (joResult.getString("rc").endsWith("0")) {
                return joResult.getJSONObject("webPage").getString("url");
            }

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            //ret.append("没有匹配结果.");
        }
        return ret.toString();
    }
}
